Skip to content

feat(roles): implement F098 agent role injection via AGENTS.md#352

Merged
pocky merged 1 commit into
mainfrom
feature/F098-agent-role-injection-agentsmd
May 18, 2026
Merged

feat(roles): implement F098 agent role injection via AGENTS.md#352
pocky merged 1 commit into
mainfrom
feature/F098-agent-role-injection-agentsmd

Conversation

@pocky
Copy link
Copy Markdown
Contributor

@pocky pocky commented May 18, 2026

Summary

  • Adds a new role: field on agent steps that loads an AGENTS.md file from a named directory and injects its body as the agent's system prompt, establishing a reusable persona across workflows (roles define who the agent is; skills define what it knows — orthogonal injection channels)
  • Implements 4-tier filesystem discovery (.awf/agents/.agents/$XDG_CONFIG_HOME/awf/agents/~/.agents/) with AWF_AGENTS_PATH exclusive override for CI/sandbox isolation; cross-client compatible with Cursor/Cline global ~/.agents/
  • Unifies role injection across all three execution paths (executeAgentStep, executeResumableAgentCall, ConversationManager.ExecuteConversation) through a single BuildRoleSystemPrompt helper to prevent divergence
  • Extends awf validate to report hard errors for missing role directories/AGENTS.md and non-blocking warnings for empty content, files > 500KB, and composed prompts > 10KB; path-traversal patterns rejected at validation time

Changes

Domain

  • internal/domain/workflow/agent_role.go: Added ErrRoleEmptyContent validation code; minor struct refinements
  • internal/domain/workflow/agent_role_test.go: Updated tests after struct/code changes

Application

  • internal/application/role_loader.go: Extracted BuildRoleSystemPrompt shared helper consolidating duplicated role resolution logic; added nil guard after ResolveAgentRole to prevent panic on (nil, nil) returns
  • internal/application/execution_service.go: Wired agentRoleRepo field; role system prompt composed before both single-turn and resumable agent calls via BuildRoleSystemPrompt; added override warning log when options.system_prompt is superseded
  • internal/application/execution_setup.go: Wired SetAgentRoleRepository for ConversationManager alongside ExecutionService
  • internal/application/conversation_manager.go: Added agentRoleRepo field + SetAgentRoleRepository() setter; ExecuteConversation now accepts workflowDir param and resolves role before state initialization; warns when options.system_prompt is overridden by composed prompt

Infrastructure

  • internal/infrastructure/roles/filesystem_repository.go: Cross-platform path-traversal fix (checks both / and \ unconditionally); filters empty search paths at init time
  • internal/infrastructure/xdg/xdg.go: Exposes agents XDG directory for discovery path construction

Interfaces — CLI

  • internal/interfaces/cli/validate.go: Added full role reference validation — disambiguates dir-exists-without-AGENTS.md from role-not-found; issues structured ErrRoleEmptyContent warning; path-traversal guard; size and combined-prompt warnings

Architecture

  • .go-arch-lint.yml: Registered infra-roles component with explicit dependency rules; added infra-roles to interfaces-cli allowed imports

Documentation

  • docs/user-guide/agent-steps.md: New "Agent Roles" section (231 lines) — discovery paths, format, composition with inline system_prompt, explicit path references, dynamic selection, validation table, conversation mode, limitations
  • docs/user-guide/workflow-syntax.md: Added role: to agent step reference table and example YAML block
  • docs/reference/error-codes.md: New USER.INPUT.MISSING_ROLE entry with resolution steps and related codes
  • README.md: Added "Agent Roles" bullet to feature list
  • docs/README.md: Linked Agent Roles section in table of contents
  • CHANGELOG.md: Added F098 entry to Unreleased section
  • CLAUDE.md: Added two architecture rules for go-arch-lint.yml updates and StripFrontmatter reuse

Tests

  • internal/application/execution_service_role_test.go: 504-line new file — covers role injection in single-turn and resumable paths, composition with inline system prompt, missing role errors, nil repo fallback, dynamic interpolation
  • internal/application/conversation_manager_role_test.go: 267-line new file — covers composed system prompt passed to provider, role-not-found propagation, nil repo behaviour in conversation mode
  • internal/application/conversation_manager_helpers_test.go: Consolidated testResolverWithValues shared helper; updated initializeConversationState call sites with new composedSystemPrompt parameter
  • internal/application/conversation_manager_tdd_test.go: Updated initializeConversationState calls to pass composed prompt param
  • internal/application/conversation_manager_test.go: Updated ExecuteConversation calls with new workflowDir parameter
  • internal/application/execution_service_conversation_step_test.go: Added missing workflowDir param to executeConversationStep calls
  • internal/application/role_loader_test.go: Removed formulaic doc comments; aligned with refactored signatures
  • internal/interfaces/cli/validate_role_test.go: 416-line new file — covers all validation branches: found, missing, dir-without-AGENTS.md, empty content, path traversal, size warnings, combined-prompt warning

Test plan

  • awf validate workflow.yaml with a valid role: go-senior reference reports ✓ and exits 0
  • awf validate workflow.yaml with a missing role reports USER.INPUT.MISSING_ROLE and exits non-zero; a role directory without AGENTS.md emits the correct disambiguation message
  • awf run workflow with role: go-senior injects AGENTS.md body as system prompt (verify via --output verbose or provider debug logs); combining with system_prompt: prepends role content separated by a blank line
  • Unit and integration tests pass: make test && make lint

Closes #351


Generated with awf commit workflow

@pocky pocky force-pushed the feature/F098-agent-role-injection-agentsmd branch from dc0647c to c6f1b6f Compare May 18, 2026 14:30
- `.go-arch-lint.yml`: register `infra-roles` component and wire dependency rules
- `CHANGELOG.md`: add F098 entry to Unreleased section
- `CLAUDE.md`: add two architecture rules for infra components and adapter patterns
- `README.md`: add Agent Roles bullet to feature list
- `docs/README.md`: add Agent Roles entry under agent-steps section
- `docs/reference/error-codes.md`: add USER.INPUT.MISSING_ROLE error code documentation
- `docs/user-guide/agent-steps.md`: add full Agent Roles section with examples and validation table
- `docs/user-guide/workflow-syntax.md`: document `role` field in agent step syntax reference
- `internal/application/conversation_manager.go`: inject role system prompt in ExecuteConversation
- `internal/application/conversation_manager_helpers_test.go`: consolidate testResolverWithValues helper
- `internal/application/conversation_manager_role_test.go`: add 267-line role injection test suite
- `internal/application/conversation_manager_tdd_test.go`: update ExecuteConversation call signatures
- `internal/application/conversation_manager_test.go`: add workflowDir parameter to test calls
- `internal/application/execution_service.go`: wire role resolution in executeAgentStep and conversation path
- `internal/application/execution_service_conversation_step_test.go`: update test signatures
- `internal/application/execution_service_role_test.go`: add 504-line role execution test suite
- `internal/application/execution_setup.go`: wire SetAgentRoleRepository in service initialization
- `internal/application/role_loader.go`: add BuildRoleSystemPrompt helper and nil guard
- `internal/application/role_loader_test.go`: remove duplicate resolver helper
- `internal/domain/workflow/agent_role.go`: add ErrRoleEmptyContent validation code
- `internal/domain/workflow/agent_role_test.go`: update tests for struct field changes
- `internal/infrastructure/roles/filesystem_repository.go`: fix cross-platform path traversal check and filter empty search paths
- `internal/infrastructure/xdg/xdg.go`: expose AWF agents XDG config dir
- `internal/interfaces/cli/validate.go`: add role reference validation with path-traversal guard
- `internal/interfaces/cli/validate_role_test.go`: add 416-line CLI validation test suite

Closes #351
@pocky pocky force-pushed the feature/F098-agent-role-injection-agentsmd branch from c6f1b6f to 690bd68 Compare May 18, 2026 15:32
@pocky pocky marked this pull request as ready for review May 18, 2026 15:52
@pocky pocky merged commit 20d437d into main May 18, 2026
5 checks passed
@pocky pocky deleted the feature/F098-agent-role-injection-agentsmd branch May 18, 2026 15:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

F098: Agent Role Injection (AGENTS.md)

1 participant